package search;

import interfaces.SearchEngine;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.Vector;

import org.compass.core.Compass;
import org.compass.core.CompassHit;
import org.compass.core.CompassHits;
import org.compass.core.CompassSession;
import org.compass.core.config.CompassConfiguration;
import org.compass.core.config.CompassConfigurationFactory;

import domain.items.Post;

public class CompassSearchEngine implements SearchEngine {
	private static final String DATA_BASE_DIR = "compassDB";
	
	private static Compass _compass;
	private static SearchEngine _compassSearchEngine;

	private CompassSearchEngine() {
		if (_compass == null) {
			cleanDataBase(new File(DATA_BASE_DIR));
	        CompassConfiguration conf = CompassConfigurationFactory.newConfiguration().setConnection(DATA_BASE_DIR);
	        conf.addClass(Post.class);
	        _compass = conf.buildCompass();
	        _compass.getConfig().addClass(Post.class);
		}
	}
	
	public static SearchEngine getInstance() {
		if (_compassSearchEngine == null) 
			_compassSearchEngine = new CompassSearchEngine();
		
		return _compassSearchEngine;
	}
	


	public synchronized Vector<Post> searchByAuthor(String authorName) {
		Vector<Post> result = searchHelper("owner:\"" + authorName + "\"");
        return result;
	}

	private Vector<Post> searchHelper(String data) {
		CompassSession session = _compass.openSession();
		CompassHits hits = session.find(data);
        CompassHit[] detachedHits = hits.detach().getHits();
		//System.out.println("Returning search rslt, found : " + hits.getLength());
        Vector<Post> result = new Vector<Post>();
        for (int i = 0; i < detachedHits.length; i++) {
			Post tPost = (Post)detachedHits[i].getData();
			tPost.setScore(detachedHits[i].getScore());
        	result.add(tPost);
		}
        session.close();
        Collections.sort(result, new Comparator<Post>() {
	        	public int compare(Post p1, Post p2) {
	        		if (p1.getScore() > p2.getScore())
	        			return -1;
	        		if (p1.getScore() == p2.getScore())
	        			return 0;
	        		return 1;
	        	}
	        });
		return result;
	}


	public synchronized Vector<Post> searchByContent(String sentence) {
		Vector<Post> result = searchHelper("contents:" + sentence);
		return result;
	}


	public synchronized Vector<Post> searchByDate(Date from, Date to) {
		SimpleDateFormat tDateFormat = new SimpleDateFormat("dd/MM/yy");
		String fromDate = tDateFormat.format(from);
		String toDate = tDateFormat.format(to);
		Vector<Post> result = searchHelper("_date:[" + fromDate + " TO " + toDate + "]");
		int i = 0;
		while (i < result.size()) {
			Post cur = result.get(i); 
			if (cur.getDate().after(to) | cur.getDate().before(from))
				result.remove(i);
			else
				i++;
		}
		return result;
	}


	public synchronized void updateSearchDB(Post newPost, Post oldPost) {
		//System.out.println("saving new post to serachDB");
		CompassSession session = _compass.openSession();
		if(oldPost!=null)
			session.delete(oldPost);
		if(newPost!=null)
			session.save(newPost);
		session.close();
	}
	
	
	private static boolean cleanDataBase(File path) {
	    if( path.exists() ) {
	      File[] files = path.listFiles();
	      for(int i=0; i<files.length; i++) {
	         if(files[i].isDirectory()) {
	           cleanDataBase(files[i]);
	         }
	         else {
	           files[i].delete();
	         }
	      }
	    }
	    return( path.delete() );
	}
}
